﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Management.Automation;
using Microsoft.Web.Administration;

using Microsoft.SharePoint.Administration;
using Microsoft.SharePoint.PowerShell;

namespace Mystery.SharePoint.PowerShell
{
    /// <summary>
    /// Base class for Cmdlets that operaate on an IIS web application
    /// </summary>
    abstract class IisApplicationCmdlet : SPSetCmdletBase<SPWebApplication>
    {
        [Parameter(Mandatory = true, ValueFromPipeline = true)]
        public SPWebApplicationPipeBind WebApplication { get; set; }
        [Parameter(Mandatory = true)]
        public SPUrlZone Zone { get; set; }

        protected override void InternalValidate()
        {
            this.DataObject = this.WebApplication.Read();

            if (this.DataObject.IisSettings.ContainsKey(this.Zone) == false)
            {
                base.ThrowTerminatingError(
                    new PSInvalidOperationException("Zone is not valid for this web application"),
                    ErrorCategory.InvalidData, this);
            }
        }

        protected override void UpdateDataObject()
        {
            string serverComment = this.DataObject.IisSettings[this.Zone].ServerComment;

            // this uses the registered servers because we then know that an IIS web site exists
            // it does not use the string array of server names since that can also be used before the server is joined to the farm
            foreach (SPServer server in SPFarm.Local.Servers)
            {
                if (server.Role != SPServerRole.Invalid)
                {
                    bool siteFound = false;
                    DateTime start = DateTime.Now;

                    while (siteFound == false)
                    {
                        ServerManager serverManager = ServerManager.OpenRemote(server.Address);

                        Site site = serverManager.Sites[serverComment];
                        if (site != null)
                        {
                            siteFound = true;

                            if (PerformActionOnSite(site, server.Address) == true)
                            {
                                serverManager.CommitChanges();
                            }
                        }
                        // during initial provisioning, the IIS web application doesn't appear immediately
                        // there is a slight delay until it is available
                        System.Threading.Thread.Sleep(2000);
                        if (DateTime.Now > start.AddMinutes(2))
                        {
                            base.WriteWarning(string.Format("Could not find {0} on {1}", serverComment, server.Address));
                            siteFound = true;
                        }
                    }
                }
            }
        }

        /// <summary>
        /// Performs action on a site
        /// </summary>
        /// <param name="site"></param>
        /// <returns>True if changes need to be commited</returns>
        protected virtual bool PerformActionOnSite(Site site, string serverName)
        {
            throw new NotImplementedException();
        }
    }
}
